
class Progress {
  isMove = false  //  设置限制setProgress函数的使用变量，防止在拖动过程中，set函数起作用导致进度条跳动
  Max = 100  //  进度条最大值
  type = 'progress'  // scroll 滚动条，可拖动；progress 进度条，不可拖动
  direction = 'horizontal'  // horizontal 水平进度条  vertical  垂直进度条
  progressBox = null  //  进度条的宽度/高度
  progressDown = null
  progressUp = null
  progressPoint = null
  flag = true
  transitionTime = 0.3
  constructor(  Obj, callback ) {
    this.init( Obj, callback )
  }
  init( obj, callback ) {

    /^[0-9.]+$/.test( obj.Max ) ? this.Max = obj.max : '';
    /(scroll|progress)/.test( obj.type ) ? this.type = obj.type.trim() : this.type = 'progress';
    /(horizontal|vertical)/.test( obj.direction ) ? this.direction = obj.direction.trim() : this.direction = 'horizontal';
    
    obj.progressBox instanceof Node ? this.progressBox = obj.progressBox : ''
    obj.up instanceof Node ? this.progressUp = obj.up : ''
    obj.down instanceof Node ? this.progressDown = obj.down : ''
    obj.point instanceof Node ? this.progressPoint = obj.point : ''
    if( this.direction === 'vertical' ) {  //  垂直进度条
      this.progressUp ? this.progressUp.style.transform = 'translateY(100%)' : '' //设置前景
      this.progressPoint ? this.progressPoint.style.transform = 'translateY(0)' : '' //设置圆点
    } else {
      this.progressUp ? this.progressUp.style.transform = 'translateX(-100%)' : '' //设置前景
      this.progressPoint ? this.progressPoint.style.transform = 'translateX(0)' : '' //设置圆点
    }
    this.progressUp ? this.progressUp.style.transition = 'all ' + this.transitionTime + 's linear' : ''
    this.progressPoint ? this.progressPoint.style.transition = 'all ' + this.transitionTime + 's linear' : ''

    this.startProgressListen( callback )

  }
  setProgressNode( up, down, point ) {  // 建议弃用
    up instanceof Node ? this.progressUp = up : this.progressUp = null
    down instanceof Node ? this.progressDown = down : this.progressDown = null
    point instanceof Node ? this.progressPoint = point : this.progressPoint = null
    this.startProgressListen()
  }
  getProgressNode() {
    return { 
      progressUp:this.progressUp,
      progressDown:this.progressDown,
      progressPoint:this.progressPoint,
      progressBox:this.progressBox
    }
  }
  startProgressListen( callback ) {  //  设置进度条监听事件
    if(document.ontouchstart === null) {  //等于null说明存在该事件
        this.PEProgressListen( callback )
    } else {
        this.PCProgressListen( callback )
    }
  }
  PCProgressListen( callback ) {  //  pc端移动事件注册
    if( this.type !== 'scroll' ) return

    this.progressDown ? this.progressDown.onmousedown = PCMouseDown.bind(this) : ''
    
    this.progressUp ? this.progressUp.onmousedown = PCMouseDown.bind(this) : ''
      
    this.progressPoint ? this.progressPoint.onmousedown = PCMouseDown.bind(this) : ''
    
    document.addEventListener('mousemove', PCMouseMove.bind(this) )
    document.addEventListener('mouseup', PCMouseUp.bind(this))

    function PCMouseMove(e) {
      if( this.flag ) return false
      this.moveSetProgress( e, callback )
      e.stopPropagation()
      return false
    }
    function PCMouseDown(e) {
      this.flag = false
      this.isMove = true
      this.progressUp ? this.progressUp.style.transition = '' : ''
      this.progressPoint ? this.progressPoint.style.transition = '' : ''
      this.moveSetProgress( e )
      e.stopPropagation()
      return false
    }
    function PCMouseUp(e) {
      this.flag = true
      if(this.isMove){
        this.isMove = false
        this.progressUp ? this.progressUp.style.transition = 'all ' + this.transitionTime + 's linear' : ''
        this.progressPoint ? this.progressPoint.style.transition = 'all ' + this.transitionTime + 's linear' : ''
        this.moveSetProgress( e )
      }
    }
     
  }
  PEProgressListen( callback ) {  //  移动端移动事件注册
    if( this.type !== 'scroll' ) return
    this.progressDown ? this.progressDown.ontouchstart = function(e) {  //给背景添加按下事件
        this.isMove = true
        this.progressUp ? this.progressUp.style.transition = '' : ''
        this.progressPoint ? this.progressPoint.style.transition = '' : ''
        this.moveSetProgress(e)
        this.progressDown.ontouchmove = touchMove.bind(this)
        this.progressDown.ontouchend = touchEnd.bind(this)
        e.stopPropagation()
        return false
    }.bind(this) : ''
      
    this.progressUp ? this.progressUp.ontouchstart = function(e) {  //给前景添加拖动事件
        this.isMove = true
        this.progressUp ? this.progressUp.style.transition = '' : ''
        this.progressPoint ? this.progressPoint.style.transition = '' : ''
        this.moveSetProgress(e)
        this.progressUp.ontouchmove = touchMove.bind(this)
        this.progressUp.ontouchend = touchEnd.bind(this)
        e.stopPropagation()
        return false
    }.bind(this) : ''
      
    this.progressPoint ? this.progressPoint.ontouchstart = function(e) {  //给圆点添加拖动事件
        this.isMove = true
        this.progressUp ? this.progressUp.style.transition = '' : ''
        this.progressPoint ? this.progressPoint.style.transition = '' : ''
        this.moveSetProgress(e)
        this.progressPoint.ontouchmove = touchMove.bind(this)
        this.progressPoint.ontouchend = touchEnd.bind(this)
        e.stopPropagation()
        return false
    }.bind(this) : ''

    function touchMove( e ) {
      this.moveSetProgress( e, callback)
      e.stopPropagation()
      return false
    }
    function touchEnd( e ) {
      this.isMove = false
      this.progressUp ? this.progressUp.style.transition = 'all ' + this.transitionTime + 's linear' : ''
      this.progressPoint ? this.progressPoint.style.transition = 'all ' + this.transitionTime + 's linear' : ''
      this.moveSetProgress( e, callback )
      e.stopPropagation()
      return false
    }

  }
  moveSetProgress( e, callback ) {  //  计算移动后的进度条长度，设置进度条
    if( this.direction === 'vertical' ) {  //  垂直进度条
      var offTop = this.progressBox.getBoundingClientRect().top + this.progressUp.offsetTop
      var offHeight = this.getHeight()
      let pin 
      if( e.changedTouches ) { //进度条移动距离就是——点击处距离屏幕左侧距离 - 进度条左侧距离屏幕左侧距离
        pin = ( e.changedTouches[0].clientY - offTop ) //移动端
      } else {
        pin = ( e.clientY - offTop )  //pc端
      }
      
      if( pin >= 0 && pin <= offHeight) {  //合法进度的长度
        this.progressUp ? this.progressUp.style.transform = 'translateY(' + pin + 'px)' : '' //设置前景
        this.progressPoint ? this.progressPoint.style.transform = 'translateY(' + ( pin - offHeight ) + 'px)' : '' //设置圆点
        let progress = (offHeight - pin) / offHeight * this.sgMax()
        callback && callback( progress, this.sgMax(), pin + offHeight , offHeight )
      } else if( pin > offHeight ) {
        this.progressUp ? this.progressUp.style.transform = 'translateY(' + offHeight + 'px)' : '' //设置前景
        this.progressPoint ? this.progressPoint.style.transform = 'translateY(0px)' : '' //设置圆点
        callback && callback( 0, this.sgMax(), 0 , offHeight )
      } else if( pin < 0 ) {
        this.progressUp ? this.progressUp.style.transform = 'translateY(0px)' : '' //设置前景
        this.progressPoint ? this.progressPoint.style.transform = 'translateY(' + -offHeight + 'px)' : '' //设置圆点
        callback && callback( this.sgMax(), this.sgMax(), offHeight , offHeight )
      }
      
    } else {  // 水平进度条
      //  获取前景左侧到屏幕左侧的距离，背景的宽度
      var offLeft = this.progressUp.offsetLeft + this.progressBox.getBoundingClientRect().left
      var offWidth = this.getWidth()
      let pin
      if( e.changedTouches ) { //进度条移动距离就是——点击处距离屏幕左侧距离 - 进度条左侧距离屏幕左侧距离
          pin = e.changedTouches[0].clientX - offLeft - offWidth  //移动端
      } else {
          pin = e.clientX - offLeft - offWidth  //pc端
      }
      if( pin < 0 && pin >= -offWidth) {  //合法进度的长度
          this.progressUp ? this.progressUp.style.transform = 'translateX(' + pin + 'px)' : '' //设置前景
          this.progressPoint ? this.progressPoint.style.transform = 'translateX(' + (pin + offWidth) + 'px)' : '' //设置圆点
          let progress = (offWidth + pin) / offWidth * this.sgMax()
          callback && callback( progress, this.sgMax(), offWidth + pin , offWidth )  //通过回调函数返回 进度 与 背景宽度的比值，将 比值 * 音乐总时长 就是 播放的位置
      } else if( pin < -offWidth ) {
          this.progressUp ? this.progressUp.style.transform = 'translateX(-' + offWidth + 'px)' : '' //设置前景
          this.progressPoint ? this.progressPoint.style.transform = 'translateX(0)' : '' //设置圆点
          callback && callback( 0, this.sgMax(), 0 , offWidth )
      } else if( pin >= 0 ) {
          this.progressUp ? this.progressUp.style.transform = 'translateX(0)' : '' //设置前景
          this.progressPoint ? this.progressPoint.style.transform = 'translateX(' + offWidth + 'px)' : '' //设置圆点
          callback && callback( this.sgMax(), this.sgMax(), offWidth , offWidth )
      }
      
    }
  }
  setProgress( progress, callback ) {  //用户设置进度条方法
    if( !this.isMove ) {
      let oldProgress = /%/g.test(progress) ? progress.replace(/%/g, '') / 100 * this.sgMax() : progress
      if( this.direction === 'vertical' ) {
        /%/g.test(progress) ? progress = this.getHeight() - progress.replace(/%/g, '') / 100 * this.getHeight() : 
        progress = this.getHeight() -  progress / this.Max * this.getHeight()
        if( progress < 0 ) {
          this.progressUp ? this.progressUp.style.transform = 'translateY(0)' : ''
        this.progressPoint ? this.progressPoint.style.transform = 'translateY(' + - this.getHeight() + 'px)' : ''
        } else {
          this.progressUp ? this.progressUp.style.transform = 'translateY(' + progress + 'px)' : ''
          this.progressPoint ? this.progressPoint.style.transform = 'translateY(' + (progress - this.getHeight()) + 'px)' : ''
        }
        callback && callback( oldProgress, this.sgMax(), this.getHeight() - progress , this.getHeight() )
      } else {
        /%/g.test(progress) ? progress = progress.replace(/%/g, '') / 100 * this.getWidth() - this.getWidth() : 
        progress = progress / this.sgMax() * this.getWidth() - this.getWidth()
        if( progress > 0 ) {
          this.progressUp ? this.progressUp.style.transform = 'translateX(0)' : ''
          this.progressPoint ? this.progressPoint.style.transform = 'translateX(' + this.getWidth() + 'px)' : ''
        } else {
          this.progressUp ? this.progressUp.style.transform = 'translateX(' + progress + 'px)' : ''
          this.progressPoint ? this.progressPoint.style.transform = 'translateX(' + (progress + this.getWidth()) + 'px)' : ''
        }
        callback && callback( oldProgress, this.sgMax(), progress + this.getWidth(), this.getWidth() )
      }
      
    }
  }
  sgMax( size  ) {
    return /^[0-9.]+$/.test(size) ? this.Max = size : this.Max
  }
  getWidth() {
    return this.progressBox ? this.progressBox.offsetWidth : 0
  }
  getHeight() {
    return this.progressBox ? this.progressBox.offsetHeight : 0
  }
}

export default Progress

